

//数据
const HeroListLeft = [
    {"spine":"zhongqibing", "x":-145,"y":-160,"speed": 6,"atk":50,"def":30,"long":false},
    {"spine":"huwei",       "x":-350,"y":-165,"speed": 8,"atk":55,"def":25,"long":false},
    {"spine":"qingqibing",  "x":-220,"y":-220,"speed":10,"atk":60,"def":20,"long":false},
    {"spine":"nuqiangbing", "x":-410,"y":-245,"speed": 7,"atk":50,"def":30,"long":true},
    {"spine":"skeleton",    "x":-265,"y":-285,"speed":12,"atk":40,"def":30,"long":false}
];
// x轴与左阵营坐标一致,处理时需要取反
const HeroListRight = [
    {"spine":"nongming",    "x":-145,"y":-160,"speed":11,"atk":50,"def":30,"long":false},
    {"spine":"bingxuenv",   "x":-350,"y":-165,"speed": 9,"atk":55,"def":25,"long":true},
    {"spine":"tuyuansu",    "x":-220,"y":-220,"speed": 5,"atk":65,"def":30,"long":false},
    {"spine":"huoqiangshou","x":-410,"y":-245,"speed": 6,"atk":40,"def":20,"long":true},
    {"spine":"zhongbubing", "x":-265,"y":-285,"speed": 7,"atk":45,"def":30,"long":false}
];
//状态
const HERO_STATE_WAIT = 1;
const HERO_STATE_MOVE = 2;
const HERO_STATE_BACK = 3;
const HERO_STATE_ATK  = 4;
const HERO_STATE_DEF  = 5;
const HERO_STATE_DIE  = 6;
const HERO_BLOOD = 100;
// 动画名称
// 等待
const ANIM_IDLE = 'Idle';
const ANIM_DIE = 'Die';
// 攻击
const ANIM_ATK = 'Attack';
const ANIM_RUN = 'Run';


cc.Class({
    extends: cc.Component,

    properties: {
        board: {
            default: null,
            type: cc.Node,
        },
        // 动画元素
        animPrefab: {
            type: cc.Prefab,
            default: null,
        }
    },
    initGameData: function() {
        this.loadIndex = 0;
        this.spineArray = [];
        this.leftHeroState = [];
        this.rightHeroState = [];
        this.orderArray = [];
        // 设置攻击队伍
        for (let i=0; i<5; ++i) {
            const left = HeroListLeft[i];
            const right = HeroListRight[i];
            this.orderArray[i] = { 'speed': left.speed, 'atk': left.atk, 'def': left.def, 'id': i, 'camp': 0, 'state': HERO_STATE_WAIT, 'blood': HERO_BLOOD };
            this.orderArray[i+5] = { 'speed': right.speed, 'atk': right.atk, 'def': right.def, 'id': i, 'camp': 1, 'state': HERO_STATE_WAIT, 'blood': HERO_BLOOD };
        }
        // 根据出手速度排序
        function sortBySpeed(a, b) {
            return b.speed - a.speed;
        }
        this.orderArray.sort(sortBySpeed);
        this.orderIndex = 0;
    },
    initGameShow: function() {
        this.leftHeroAnim = [];
        this.rightHeroAnim = [];
        // 初始化阵容，没有动画播放
        for(let i=0; i<5; ++i) {
            // 初始化左边阵容
            let data = HeroListLeft[i];
            this.leftHeroAnim[i] = cc.instantiate(this.animPrefab);
            this.leftHeroAnim[i].setPosition(cc.v2(data.x, data.y));
            this.board.addChild(this.leftHeroAnim[i]);
            // 初始化右边阵容
            data = HeroListRight[i];
            this.rightHeroAnim[i] = cc.instantiate(this.animPrefab);
            this.rightHeroAnim[i].setPosition(cc.v2(-data.x, data.y));
            this.board.addChild(this.rightHeroAnim[i]);
            this.rightHeroAnim[i].scaleX = -1;
        }
        this.loadAnim();
    },

    loadAnim: function () {
        let data;
        if(this.loadIndex >= 5 && this.loadIndex <= 9) {
            data = HeroListRight[this.loadIndex-5];
        } else if (this.loadIndex < 5) {
            data = HeroListLeft[this.loadIndex];
        } else {
            return
        }
        const loadAnimCallback = function (err, res) {
            this.spineArray[this.loadIndex] = res;
            // 默认动作
            let anim;
            if(this.loadIndex < 5) {
                anim = this.leftHeroAnim[this.loadIndex].getComponent(sp.Skeleton);
            } else {
                anim = this.rightHeroAnim[this.loadIndex-5].getComponent(sp.Skeleton);
            }
            anim.skeletonData = res;
            anim.animation = ANIM_IDLE;
            this.loadIndex += 1;
            // 加载下一个动画
            this.loadAnim();
        }.bind(this);
        cc.loader.loadRes(`spine/${data.spine}`, sp.SkeletonData, loadAnimCallback);
    },
    startGame: function() {
        this.orderIndex = 0;
        this.nextAttack();
    },

    nextAttack: function(){
        if(this.orderIndex > 9) {
            this.orderIndex = 0;
        }
        let attacker = this.orderArray[this.orderIndex];
        if(attacker.state === HERO_STATE_WAIT) {
            // move to army
            this.setAnimState(attacker, HERO_STATE_MOVE);
        } else {
            this.orderIndex = this.orderIndex+1;
            this.nextAttack();
        }
    },

    // 更新动画状态
    setAnimState: function(obj, state) {
        obj.state = state;
        if(state === HERO_STATE_MOVE) {
            // 目标阵营
            let targetCamp = 1;
            let target = null;
            let animHandler = this.leftHeroAnim[obj.id];
            // 是否远程攻击
            let isLong = HeroListLeft[obj.id].long;
            if(obj.camp === 1) {
                targetCamp = 0;
                isLong = HeroListRight[obj.id].long;
                animHandler = this.rightHeroAnim[obj.id];
            }
            // 查找攻击对象
            for(let i=0; i<10; ++i) {
                if(this.orderArray[i].camp === targetCamp && this.orderArray[i].state !== HERO_STATE_DIE) {
                    this.targetIndex = i;
                    target = this.orderArray[i];
                    this.targetId = target.id;
                    cc.log(`choose target id = ${target.id}, camp = ${targetCamp}`);
                }
            }
            if(target == null) {
                // 对方全部死亡，游戏结束
                return
            }
            cc.log(`attack target id = ${target.id}, camp = ${targetCamp}, attacker = ${obj.id}, camp =${obj.camp}`);
            // move to target position
            let targetPos = cc.v2(0,0);
            if(isLong) {
                // 远程攻击
                this.setAnimState(obj, HERO_STATE_ATK);
                return;
            }
            if(targetCamp === 1) {
                // 右边
                targetPos.x = -(HeroListRight[target.id].x+40);
                targetPos.y = HeroListRight[target.id].y;
            } else {
                targetPos.x = HeroListLeft[target.id].x+40;
                targetPos.y = HeroListLeft[target.id].y;
            }
            const callback = cc.callFunc(function () {
                // enter攻击状态
                this.setAnimState(obj, HERO_STATE_ATK);
            }, this);
            animHandler.runAction(cc.sequence(cc.moveTo(0.5, targetPos.x, targetPos.y), callback))
        } else if (state === HERO_STATE_ATK) {
            // 攻击
            let animHandle = this.leftHeroAnim[obj.id];
            if(obj.camp === 1) {
                animHandle = this.rightHeroAnim[obj.id];
            }
            animHandle.getComponent(sp.Skeleton).setAnimation(0, ANIM_ATK, false);
            animHandle.getComponent(sp.Skeleton).setCompleteListener( trackEntry => {
                // 计算减小的血量
                let targetDef = HeroListLeft[this.orderArray[this.targetIndex].id].def;
                let objAtk = HeroListRight[obj.id].atk;
                // 被攻击对象
                let targetHandle = this.rightHeroAnim[this.orderArray[this.targetIndex].id];
                let targetPos = cc.v2(0, 0);
                targetPos.x = HeroListLeft[obj.id].x;
                targetPos.y = HeroListLeft[obj.id].y;
                if(obj.camp === 1) {
                    targetDef = HeroListRight[this.orderArray[this.targetIndex].id].def;
                    objAtk = HeroListLeft[obj.id].atk;
                    targetHandle = this.leftHeroAnim[this.orderArray[this.targetIndex].id];
                    targetPos.x = -HeroListRight[obj.id].x;
                    targetPos.y = HeroListRight[obj.id].y;
                }
                this.orderArray[this.targetIndex].blood = this.orderArray[this.targetIndex].blood + targetDef - objAtk;
                if (this.orderArray[this.targetIndex].blood > 0) {
                    // 掉血
                    targetHandle.getComponent('heroControl').setBlood(this.orderArray[this.targetIndex].blood/100);
                } else {
                    cc.log(`target id = ${this.targetId} die`);
                    targetHandle.getComponent('heroControl').setBlood(0);
                    this.setAnimState(this.orderArray[this.targetIndex], HERO_STATE_DIE);
                }
                // 退回到原来位置
                // 等待死亡动作完成
                animHandle.getComponent(sp.Skeleton).setCompleteListener(trackEntry => {
                });
                animHandle.getComponent(sp.Skeleton).animation = ANIM_RUN;
                const callback = cc.callFunc(function () {
                    this.setAnimState(obj, HERO_STATE_WAIT);
                }, this);
                animHandle.runAction(cc.sequence(cc.moveTo(0.5, targetPos.x, targetPos.y), callback));
            });
            cc.log(`in attack attacker id = ${obj.id}, target index in order array = ${this.targetIndex}, targetId = ${this.targetId}`);
        }  else if (state === HERO_STATE_DIE) {
            // 死亡
            let animHandle = this.leftHeroAnim[obj.id];
            if(obj.camp === 1) {
                animHandle = this.rightHeroAnim[obj.id];
            }
            animHandle.getComponent(sp.Skeleton).setAnimation(0, ANIM_DIE, false);
            animHandle.getComponent(sp.Skeleton).setCompleteListener( trackEntry => {
                animHandle.active = false;
            });
        } else if (state === HERO_STATE_WAIT) {
            // 回到初始状态
            let animHandle = this.leftHeroAnim[obj.id];
            if (obj.camp === 1) {
                animHandle = this.rightHeroAnim[obj.id];
            }
            animHandle.getComponent(sp.Skeleton).animation = ANIM_IDLE;
            this.orderIndex += 1;
            this.nextAttack();
        }

    },
    // LIFE-CYCLE CALLBACKS:

    onLoad () {
        // init data
        this.initGameData();
        // init show
        this.initGameShow();
        // start game
        this.startGame();
    },

    start () {

    },

    // update (dt) {},
});
